package com.glsc.ngateway.platform.service.itflow.flowstrategy.equipmentOffline.taskPostHandler;

import com.glsc.ngateway.common.api.common.enums.RabbitExcQueConstant;
import com.glsc.ngateway.common.base.domain.mysql.gateway.platform.it.ItServerDevice;
import com.glsc.ngateway.common.base.domain.mysql.gateway.platform.flow.FlowFormEquipmentOffline;
import com.glsc.ngateway.common.base.domain.mysql.gateway.platform.flow.FlowFormEquipmentOfflineCloudDeviceDetail;
import com.glsc.ngateway.common.base.domain.mysql.gateway.platform.flow.FlowFormEquipmentOfflineServerDetail;
import com.glsc.ngateway.common.base.domain.mysql.gateway.platform.flow.FlowFormEquipmentOfflineVirtualDeviceDetail;
import com.glsc.ngateway.common.api.flowable.dto.task.doTaskParam.equipment.EquipmentPassParamDto;
import com.glsc.ngateway.common.api.flowable.dto.task.doTaskParam.equipment.EquipmentRejectParamDto;
import com.glsc.ngateway.common.api.flowable.dto.task.formData.equipment.EquipmentOfflineTaskFormDataDto;
import com.glsc.ngateway.common.api.flowable.dto.task.formData.equipment.domainDto.FlowFormEquipmentOfflineDto;
import com.glsc.ngateway.common.api.flowable.dto.task.message.EquipmentFlowMessageDto;
import com.glsc.ngateway.common.api.flowable.resp.ResponseSituationDto;
import com.glsc.ngateway.common.base.exception.PlatformException;
import com.glsc.ngateway.common.base.repo.mysql.gateway.platform.FlowFormEquipmentOfflineCloudDeviceRepo;
import com.glsc.ngateway.common.base.repo.mysql.gateway.platform.FlowFormEquipmentOfflineRepo;
import com.glsc.ngateway.common.base.repo.mysql.gateway.platform.FlowFormEquipmentOfflineServerRepo;
import com.glsc.ngateway.common.base.repo.mysql.gateway.platform.FlowFormEquipmentOfflineVirtualDeviceRepo;
import com.glsc.ngateway.platform.service.FlowCommonService;
import com.glsc.ngateway.platform.service.it.CloudService;
import com.glsc.ngateway.platform.service.it.ServerService;
import com.glsc.ngateway.platform.service.it.VirtualService;
import com.glsc.ngateway.platform.service.itflow.flowstrategy.AbstractHandlerHelper;
import com.glsc.ngateway.platform.utils.MqUtil;
import com.glsc.ngateway.common.base.enums.itflow.ITFlowStatus;
import io.jsonwebtoken.lang.Collections;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.validation.constraints.NotNull;
import java.util.List;

/**
 * 设备下线节点辅助类
 * @author xuchang
 */
@Component
public class EOStepHandlerHelper extends AbstractHandlerHelper {

    @Autowired
    private ServerService serverService;

    @Autowired
    private CloudService cloudService;

    @Autowired
    private VirtualService virtualService;

    @Autowired
    private FlowFormEquipmentOfflineServerRepo equipmentOfflineServerRepo;

    @Autowired
    private FlowFormEquipmentOfflineVirtualDeviceRepo equipmentOfflineVirtualDeviceRepo;

    @Autowired
    private FlowFormEquipmentOfflineCloudDeviceRepo equipmentOfflineCloudServerRepo;

    @Autowired
    private FlowFormEquipmentOfflineRepo equipmentOfflineRepo;

    @Autowired
    private FlowCommonService flowCommonService;

    /**
     * 最后审批后置处理
     */
    protected void endTaskAfterHandle(EquipmentPassParamDto<FlowFormEquipmentOfflineDto, EquipmentOfflineTaskFormDataDto> param, String operator, @NotNull String mqCodeKey) {
        ResponseSituationDto processInfo = flowCommonService.getProcessInfo(param.getProcessId());
        if (Collections.isEmpty(processInfo.getCurrentTaskInfoDtoList())) {
            EquipmentFlowMessageDto message = new EquipmentFlowMessageDto();
            FlowFormEquipmentOffline offline = equipmentOfflineRepo.findByProcessId(param.getProcessId());
            message.setMainFormId(offline.getId());
            message.setDefineKey(mqCodeKey);
            message.setOperator(operator);
            MqUtil.sendMessage(RabbitExcQueConstant.AMPRODUCT_EXCHANGE_DEFAULT, RabbitExcQueConstant.AMPRODUCT_QUEUE_GATEWAY_FLOW_REMIND, message);
        }
    }

    /**
     * 驳回后置处理方法
     */
    protected void afterHandle(@NotNull EquipmentRejectParamDto param, @NotNull String operator) {
        List<FlowFormEquipmentOffline> formDataList = equipmentOfflineRepo.findAllByProcessId(param.getProcessId());
        formDataList.forEach(f->{
            f.setUpdateAccount(operator);
        });
        equipmentOfflineRepo.saveAll(formDataList);
    }

    public void offlineEquipment(Long mainFormId) {
        FlowFormEquipmentOffline offline = equipmentOfflineRepo.findById(mainFormId)
                .orElseThrow(()-> PlatformException.error(String.format("设备下架，消息处理异常：未找到主表数据，%s", mainFormId)));
        if(offline.getIsClose() == 0) {
            //下架服务器
            offlineServer(mainFormId);
            //下架虚拟机
            offlineVirtualDevice(mainFormId);
            //下架云平台
            offlineCloudServer(mainFormId);
            offline.setStatus(ITFlowStatus.END.getCode());
            offline.setIsClose(1);
            equipmentOfflineRepo.save(offline);
        }
    }

    private void offlineServer(Long mainFormId) {
        List<FlowFormEquipmentOfflineServerDetail> offlineServerlList = equipmentOfflineServerRepo.findByEquipmentOfflineId(mainFormId);
        offlineServerlList.forEach(server -> {
            String devId = String.valueOf(server.getServerDevId());
//            String ip2 = server.getIp2();
            ItServerDevice dev = serverService.findByDevId(devId);
            if (dev != null) {
//                dev.setIp2(ip2);
                dev.setMachineStatus("116");
                serverService.addOrUpdateServer(dev);
            }
        });
    }

    private void offlineVirtualDevice(Long mainFormId) {
        List<FlowFormEquipmentOfflineVirtualDeviceDetail> offlineVirtualList = equipmentOfflineVirtualDeviceRepo.findByEquipmentOfflineId(mainFormId);
        offlineVirtualList.forEach(virtual -> {
            virtualService.deleteVirtual(String.valueOf(virtual.getVirtualDeviceId()));
        });
    }

    private void offlineCloudServer(Long mainFormId) {
        List<FlowFormEquipmentOfflineCloudDeviceDetail> offlineCloudList = equipmentOfflineCloudServerRepo.findByEquipmentOfflineId(mainFormId);
        offlineCloudList.forEach(cloud -> {
            cloudService.deleteCloud(String.valueOf(cloud.getCloudDevId()));
        });
    }
}
